#include <jni.h>
#include "jendocreat.h"
#include "dnamap.h"
#include <iostream>
using namespace std;
using namespace dnamap;

string translate(const char* dnastr, const char* cfname);
sitelist synmut(string& dnastr, const char* cfname, const char* sitestr);

JNIEXPORT jstring JNICALL Java_endo_clink_translate
  (JNIEnv *env, jobject obj, jstring jdnaseq, jstring jcodonfname)
{
    const char* nativeDNAseq = env -> GetStringUTFChars(jdnaseq, JNI_FALSE);
    const char* nativecodonfname = env -> GetStringUTFChars(jcodonfname, JNI_FALSE);
    string res = translate(nativeDNAseq, nativecodonfname);
    jstring tstr = env -> NewStringUTF(res.c_str());
    return tstr;
}

JNIEXPORT jobject JNICALL Java_endo_clink_sites
  (JNIEnv *env, jobject obj, jstring jdnaseq, jstring jcodonfname, jstring jsiteseq)
{
    const char* nativeDNAseq = env -> GetStringUTFChars(jdnaseq, JNI_FALSE);
    const char* nativecodonfname = env -> GetStringUTFChars(jcodonfname, JNI_FALSE);
    const char* nativeSiteseq = env -> GetStringUTFChars(jsiteseq, JNI_FALSE);
    string DNAseq = nativeDNAseq;
    sitelist mysite = synmut(DNAseq, nativecodonfname, nativeSiteseq);
    int size = mysite.length();

    jclass clazz = env -> FindClass("SeqSites");
    if(clazz == NULL)
    {
        return NULL;
    }
    jobject resobj = env -> AllocObject(clazz);
    jfieldID fid = env -> GetFieldID(clazz, "sites", "[I");
    if(fid == NULL)
    {
        return NULL;
    }
    jint *fill;
    jintArray jsites = env -> NewIntArray(size);
    if(jsites == NULL)
    {
        return NULL;
    }
    fill = new jint[size];
    for(int i = 0; i < size; i++)
    {
        fill[i] = mysite[i];
    }
    env -> SetIntArrayRegion(jsites, 0, size, fill);
    delete fill;
    fill = NULL;

    env -> SetObjectField(resobj, fid, jsites);
    fid = env -> GetFieldID(clazz, "sequence", "Ljava/lang/String;");
    jstring jmodseq = env -> NewStringUTF(DNAseq.c_str());
    env -> SetObjectField(resobj, fid, jmodseq);
    return resobj;
}

string translate(const char* dnastr, const char* cfname)
{
    static char fname[1024];
    static protrans mytrans;
    if(strcmp(fname, cfname) != 0)
    {
        strcpy(fname, cfname);
        mytrans.readcodon(cfname);
    }
    dnaseq myseq;
    myseq.enter(dnastr);
    return mytrans.translate(myseq.getframe(0));
}

sitelist synmut(string& dnastr, const char* cfname, const char* sitestr)
{
    static char fname[1024];
    static protrans mytrans;
    static string mydnaseq;
    static dnaseq myseq;
    if(strcmp(fname, cfname) != 0)
    {
        strcpy(fname, cfname);
        mytrans.readcodon(cfname);
    }
    if(mydnaseq != dnastr)
    {
        mydnaseq = dnastr;
        myseq.enter(dnastr.c_str());
    }
    restriction rsite(sitestr, "A");
    string a = myseq.getframe(0);
    sitelist mysites = mytrans.synmut(a, rsite.siteseq);
    dnastr = a;
    return mysites;
}

